/*
 * Copyright 2011 Dominik Pretzsch <dominik.pretzsch at gmail.com>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.blacksheep.jmoteextract.progress;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Dominik Pretzsch <dominik.pretzsch at gmail.com>
 */
class ProgressUpdateThread extends Thread {

    private static ProgressUpdateQueue QUEUE;
    private static ProgressManager progressManager;
    
    private static final Logger LOGGER = Logger.getLogger(ProgressUpdateThread.class.getName());
    
    public ProgressUpdateThread() {
        QUEUE = ProgressUpdateQueue.getInstance();
        progressManager = ProgressManager.getInstance();
        
        this.setName(this.getClass().getName());
        this.setDaemon(true);
    }
    
    @Override
    public void run() {
        while (true) {
            checkQueueForUpdates();
        }
    }    
    
    private void checkQueueForUpdates() {
        LOGGER.log(Level.FINE, "Try to checkQueueForUpdates...");
        Object[] typeDataBundle = QUEUE.dequeue();
        int type = (Integer) typeDataBundle[0];
        Object[] data = (Object[]) typeDataBundle[1];     
        updateProgress(type, data);
    }
    
    private void updateProgress(Integer type, Object[] data) {
        LOGGER.log(Level.FINE, "Try to updateProgress type {0}...", type);
        if (type == null || data == null) {
            return;
        }
        switch (type) {
            case ProgressUpdate.TYPE_TOTAL_BYTES:
            {
                int hash   = (Integer) data[0];
                long bytes = (Long)    data[1];                
                updateTotalBytes(hash, bytes);
            }
                break;
            case ProgressUpdate.TYPE_COMPLETE_BYTES:
            {
                int hash   = (Integer) data[0];
                long bytes = (Long)    data[1];                
                updateCompleteBytes(hash, bytes);
            }
                break;
            case ProgressUpdate.TYPE_LAST_ITEM:
            {
                int hash     = (Integer) data[0];
                int itemHash = (Integer) data[1];
                String path  = (String)  data[2];                
                updateLastItem(hash, itemHash, path);
            }
                break;
            case ProgressUpdate.TYPE_ERROR_MSG:
            {
                int hash   = (Integer) data[0];
                String msg = (String)  data[1];
                updateErrorMessage(hash, msg);                
            }
                break;
            case ProgressUpdate.TYPE_SET_FINISHED:
            {
                int hash   = (Integer) data[0];
                updateSetFinished(hash);                
            }
                break;
            default:
                LOGGER.log(Level.FINE, "... Unknown type. Can't update.");
                break;
        }
    }
    
    private void updateTotalBytes(int hash, long bytes) {
        LOGGER.log(Level.FINE, "Updating: {0} Bytes in total for {1}...", new Object[] {bytes, hash});
        progressManager.setBytesTotal(hash, bytes);
    }
    
    private void updateCompleteBytes(int hash, long bytes) {
        LOGGER.log(Level.FINE, "Updating: {0} Bytes completed for {1}...", new Object[] {bytes, hash});
        progressManager.setBytesDone(hash, bytes);
    }
    
    private void updateLastItem(int hash, int itemHash, String path) {
        LOGGER.log(Level.FINE, "Updating: {0}:{1} is last item for {2}...", new Object[] {itemHash, path, hash});
        progressManager.setLastItem(hash, itemHash, path);
    }
    
    private void updateErrorMessage(int hash, String msg) {
        LOGGER.log(Level.FINE, "Updating: '{0}' is error message for {1}...", new Object[] {msg, hash});
        progressManager.setErrorMsg(hash, msg);
    }
    
    private void updateSetFinished(int hash) {
        LOGGER.log(Level.FINE, "Updating: Setting {1} to finished...", hash);
        progressManager.setFinished(hash);
    }
}
